package com.geo.auth.entity;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.Builder;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import java.time.LocalDateTime;

/**
 * 用户实体类
 * 
 * @author GEO Team
 * @version 1.0
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName("sys_user")
public class User {
    
    /**
     * 用户ID
     */
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private String id;
    
    /**
     * 用户名
     */
    @NotBlank(message = "用户名不能为空")
    @Size(min = 3, max = 50, message = "用户名长度必须在3-50个字符之间")
    @TableField("username")
    private String username;
    
    /**
     * 密码（加密存储）
     */
    @NotBlank(message = "密码不能为空")
    @Size(min = 6, max = 100, message = "密码长度必须在6-100个字符之间")
    @TableField("password")
    private String password;
    
    /**
     * 邮箱
     */
    @Email(message = "邮箱格式不正确")
    @TableField("email")
    private String email;
    
    /**
     * 手机号
     */
    @TableField("phone")
    private String phone;
    
    /**
     * 昵称
     */
    @TableField("nickname")
    private String nickname;
    
    /**
     * 头像URL
     */
    @TableField("avatar")
    private String avatar;
    
    /**
     * 用户状态
     */
    @TableField("status")
    private UserStatus status;
    
    /**
     * 用户类型
     */
    @TableField("user_type")
    private UserType userType;
    
    /**
     * 最后登录时间
     */
    @TableField("last_login_time")
    private LocalDateTime lastLoginTime;
    
    /**
     * 最后登录IP
     */
    @TableField("last_login_ip")
    private String lastLoginIp;
    
    /**
     * 登录失败次数
     */
    @TableField("login_failure_count")
    private Integer loginFailureCount;
    
    /**
     * 账户锁定时间
     */
    @TableField("locked_until")
    private LocalDateTime lockedUntil;
    
    /**
     * 备注
     */
    @TableField("remark")
    private String remark;
    
    /**
     * 创建时间
     */
    @TableField(value = "created_at", fill = FieldFill.INSERT)
    private LocalDateTime createdAt;
    
    /**
     * 更新时间
     */
    @TableField(value = "updated_at", fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updatedAt;
    
    /**
     * 创建者ID
     */
    @TableField("created_by")
    private String createdBy;
    
    /**
     * 更新者ID
     */
    @TableField("updated_by")
    private String updatedBy;
    
    /**
     * 逻辑删除标志
     */
    @TableLogic
    @TableField("deleted")
    private Integer deleted;
    
    /**
     * 用户状态枚举
     */
    public enum UserStatus {
        ACTIVE(1, "激活"),
        INACTIVE(0, "未激活"),
        LOCKED(-1, "锁定"),
        DISABLED(-2, "禁用");
        
        private final Integer code;
        private final String description;
        
        UserStatus(Integer code, String description) {
            this.code = code;
            this.description = description;
        }
        
        public Integer getCode() {
            return code;
        }
        
        public String getDescription() {
            return description;
        }
        
        public static UserStatus fromCode(Integer code) {
            for (UserStatus status : values()) {
                if (status.code.equals(code)) {
                    return status;
                }
            }
            return INACTIVE;
        }
    }
    
    /**
     * 用户类型枚举
     */
    public enum UserType {
        ADMIN("admin", "管理员"),
        MERCHANT("merchant", "商家"),
        OPERATOR("operator", "运营人员"),
        GUEST("guest", "访客");
        
        private final String code;
        private final String description;
        
        UserType(String code, String description) {
            this.code = code;
            this.description = description;
        }
        
        public String getCode() {
            return code;
        }
        
        public String getDescription() {
            return description;
        }
        
        public static UserType fromCode(String code) {
            for (UserType type : values()) {
                if (type.code.equals(code)) {
                    return type;
                }
            }
            return GUEST;
        }
    }
    
    /**
     * 检查用户是否可用
     * @return 是否可用
     */
    public boolean isAvailable() {
        return status == UserStatus.ACTIVE && 
               (lockedUntil == null || LocalDateTime.now().isAfter(lockedUntil));
    }
    
    /**
     * 检查是否需要解锁
     * @return 是否需要解锁
     */
    public boolean shouldUnlock() {
        return status == UserStatus.LOCKED && 
               lockedUntil != null && 
               LocalDateTime.now().isAfter(lockedUntil);
    }
    
    /**
     * 重置登录失败次数
     */
    public void resetLoginFailureCount() {
        this.loginFailureCount = 0;
        this.lockedUntil = null;
        if (this.status == UserStatus.LOCKED) {
            this.status = UserStatus.ACTIVE;
        }
    }
    
    /**
     * 增加登录失败次数
     * @param maxFailureCount 最大失败次数
     * @param lockDurationMinutes 锁定时长（分钟）
     */
    public void incrementLoginFailureCount(int maxFailureCount, int lockDurationMinutes) {
        this.loginFailureCount = (this.loginFailureCount == null ? 0 : this.loginFailureCount) + 1;
        
        if (this.loginFailureCount >= maxFailureCount) {
            this.status = UserStatus.LOCKED;
            this.lockedUntil = LocalDateTime.now().plusMinutes(lockDurationMinutes);
        }
    }
    
    // 手动添加getter方法以解决编译问题
    public String getPassword() {
        return password;
    }
    
    public String getId() {
        return id;
    }
    
    public String getNickname() {
        return nickname;
    }
    
    public LocalDateTime getLastLoginTime() {
        return lastLoginTime;
    }
    
    public LocalDateTime getCreatedAt() {
        return createdAt;
    }
    
    // 添加更多缺失的getter方法
    public String getUsername() {
        return username;
    }
    
    public String getAvatar() {
        return avatar;
    }
    
    public UserType getUserType() {
        return userType;
    }
    
    // 添加缺失的getter方法
    public String getEmail() {
        return email;
    }
    
    public String getPhone() {
        return phone;
    }
    
    public UserStatus getStatus() {
        return status;
    }
    
    public Integer getLoginFailureCount() {
        return loginFailureCount;
    }
    
    public void setLastLoginTime(LocalDateTime lastLoginTime) {
        this.lastLoginTime = lastLoginTime;
    }
    
    public void setLastLoginIp(String lastLoginIp) {
        this.lastLoginIp = lastLoginIp;
    }
    
    // 添加builder方法
    public static UserBuilder builder() {
        return new UserBuilder();
    }
    
    public static class UserBuilder {
        private String id;
        private String username;
        private String password;
        private String email;
        private String phone;
        private String nickname;
        private String avatar;
        private UserStatus status;
        private UserType userType;
        private LocalDateTime lastLoginTime;
        private String lastLoginIp;
        private Integer loginFailureCount;
        private LocalDateTime lockedUntil;
        private String remark;
        private LocalDateTime createdAt;
        private LocalDateTime updatedAt;
        private String createdBy;
        private String updatedBy;
        private Integer deleted;
        
        public UserBuilder id(String id) {
            this.id = id;
            return this;
        }
        
        public UserBuilder username(String username) {
            this.username = username;
            return this;
        }
        
        public UserBuilder password(String password) {
            this.password = password;
            return this;
        }
        
        public UserBuilder email(String email) {
            this.email = email;
            return this;
        }
        
        public UserBuilder phone(String phone) {
            this.phone = phone;
            return this;
        }
        
        public UserBuilder nickname(String nickname) {
            this.nickname = nickname;
            return this;
        }
        
        public UserBuilder avatar(String avatar) {
            this.avatar = avatar;
            return this;
        }
        
        public UserBuilder status(UserStatus status) {
            this.status = status;
            return this;
        }
        
        public UserBuilder userType(UserType userType) {
            this.userType = userType;
            return this;
        }
        
        public UserBuilder lastLoginTime(LocalDateTime lastLoginTime) {
            this.lastLoginTime = lastLoginTime;
            return this;
        }
        
        public UserBuilder lastLoginIp(String lastLoginIp) {
            this.lastLoginIp = lastLoginIp;
            return this;
        }
        
        public UserBuilder loginFailureCount(Integer loginFailureCount) {
            this.loginFailureCount = loginFailureCount;
            return this;
        }
        
        public UserBuilder lockedUntil(LocalDateTime lockedUntil) {
            this.lockedUntil = lockedUntil;
            return this;
        }
        
        public UserBuilder remark(String remark) {
            this.remark = remark;
            return this;
        }
        
        public UserBuilder createdAt(LocalDateTime createdAt) {
            this.createdAt = createdAt;
            return this;
        }
        
        public UserBuilder updatedAt(LocalDateTime updatedAt) {
            this.updatedAt = updatedAt;
            return this;
        }
        
        public UserBuilder createdBy(String createdBy) {
            this.createdBy = createdBy;
            return this;
        }
        
        public UserBuilder updatedBy(String updatedBy) {
            this.updatedBy = updatedBy;
            return this;
        }
        
        public UserBuilder deleted(Integer deleted) {
            this.deleted = deleted;
            return this;
        }
        
        public User build() {
            User user = new User();
            user.id = this.id;
            user.username = this.username;
            user.password = this.password;
            user.email = this.email;
            user.phone = this.phone;
            user.nickname = this.nickname;
            user.avatar = this.avatar;
            user.status = this.status;
            user.userType = this.userType;
            user.lastLoginTime = this.lastLoginTime;
            user.lastLoginIp = this.lastLoginIp;
            user.loginFailureCount = this.loginFailureCount;
            user.lockedUntil = this.lockedUntil;
            user.remark = this.remark;
            user.createdAt = this.createdAt;
            user.updatedAt = this.updatedAt;
            user.createdBy = this.createdBy;
            user.updatedBy = this.updatedBy;
            user.deleted = this.deleted;
            return user;
        }
    }
}